package cz.worktracker.controller;

import cz.worktracker.HibernateUtil;
import cz.worktracker.model.entities.User;
import javax.faces.bean.ManagedBean;
import org.hibernate.Transaction;
import org.hibernate.Session;
import java.security.*;
import java.math.*;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.enterprise.context.RequestScoped;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.inject.Named;
import org.hibernate.Query;

/**
 * RegisterBean
 * Controller for register new user to system
 * @since 2010-04-20
 * @author kyjovsky
 */
@ManagedBean
@RequestScoped
@Named
public class RegisterBean {

    User user;
    private Session session;
    @Inject
    AdminManager adminManager;

    public RegisterBean() {
    }

    /**
     * Constructor
     */
    @PostConstruct
    public void construct() {
        if (user == null) {
            user = new User();
        }
    }

    /**
     * Destructor
     */
    @PreDestroy
    public void destroy() {
        user = null;
    }

    /**
     * Get user data
     * @return User
     */
    public User getUser() {
        return user;
    }

    /**
     * Set user data
     * @param user
     */
    public void setUser(User user) {
        this.user = user;
    }

    /**
     * MD5 hash function
     * @param text input text
     * @return MD5 hash
     * @throws Exception
     */
    public static String MD5(String text) throws Exception {
        MessageDigest m = MessageDigest.getInstance("MD5");
        m.update(text.getBytes(), 0, text.length());
        String hash = new BigInteger(1, m.digest()).toString(16);
        int len = hash.length();
        for (int i = 32; i > len; i--) {
            hash = "0" + hash;
        }
        return (hash);
    }

    /**
     * Register new user
     * Save user data to db
     * @return String navigation
     */
    public String create() {
        if (user != null) {
            try {
                user.setPassword(MD5(user.getPassword()));
                user.setRole("USER");
                user.setIsActive("y");
                user.setIsAdmin("n");

                session = HibernateUtil.getSessionFactory().getCurrentSession();
                Transaction tx = session.beginTransaction();

                session.save(user);

                tx.commit();

                user = null;
                adminManager.destroy();

            } catch (Exception e) {
                return null;
            }
        }
        return "registerSuccess";
    }

    /**
     * Login validator.
     * Validate the correctness of login.
     * If login value is using by other user, this method send false message.
     * @param context
     * @param toValidate
     * @param value
     */
    public void validateLogin(FacesContext context, UIComponent toValidate, Object value) {
        String user_name = (String) value;

        if (user_name.length() == 0) {
            return;
        }

        session = HibernateUtil.getSessionFactory().getCurrentSession();
        Transaction tx = (Transaction) session.beginTransaction();
        String hql = "from User as user where user.login = '" + user_name + "'";
        Query query = session.createQuery(hql);
        query.setMaxResults(1);

        if (query.uniqueResult() != null) {
            ((UIInput) toValidate).setValid(false);
            FacesMessage message = new FacesMessage(((UIInput) toValidate).getValidatorMessage());
            context.addMessage(toValidate.getClientId(context), message);

        }
    }
}
